package aclInfoCollector.filesAnalysers.code;

import java.util.ArrayList;
import java.util.HashMap;

import aclInfoCollector.utils.specialString.StringOperation;

public abstract class CodeFileAnalyser implements  ICodeFileAnalyser
{
	protected ArrayList<String> classes;
	protected ArrayList<String> interfaces;
	protected ArrayList<String> primitives;
	protected HashMap<String, ArrayList<String>> classesWithInterfaces;
	protected HashMap<String, ArrayList<String>> classesWithSuperTypes;
	protected HashMap<String, ArrayList<StringOperation>> interfacesWithOperations;
	protected HashMap<String, ArrayList<String>> interfacesWithSuperInterFaces;
	
	
		/**
	 * construit un classFinder initialise les attributs
	 */

	public CodeFileAnalyser() {
		classes = new ArrayList<String>();
		interfaces = new ArrayList<String>();
		primitives = new ArrayList<String>();
		classesWithInterfaces = new HashMap<String, ArrayList<String>>();
		classesWithSuperTypes = new HashMap<String, ArrayList<String>>();
		interfacesWithOperations = new HashMap<String, ArrayList<StringOperation>>();
		interfacesWithSuperInterFaces = new HashMap<String, ArrayList<String>>();
	}

	/**
	 * construit un classFinder initialise les attributs et lance une analyse
	 * sur directoryPath
	 */
	public CodeFileAnalyser(String directoryPath) {
		classes = new ArrayList<String>();
		interfaces = new ArrayList<String>();
		primitives = new ArrayList<String>();
		classesWithInterfaces = new HashMap<String, ArrayList<String>>();
		classesWithSuperTypes = new HashMap<String, ArrayList<String>>();
		interfacesWithOperations = new HashMap<String, ArrayList<StringOperation>>();
		interfacesWithSuperInterFaces = new HashMap<String, ArrayList<String>>();
		launchAnalysis(directoryPath);
	}
	
	/**
	 * ajoute une classe en verifiant si elle n'a pas deja été ajoutée
	 */
	public void addClass(String s) {
		if (!classes.contains(s)) {
			classes.add(s);
		}
	}

	/**
	 * Ajoute les classes et de leurs interfaces a l'attribut
	 * classesWithInterfaces
	 * 
	 * @param list
	 */
	public void addClassesWithInterfaces(HashMap<String, ArrayList<String>> list) {
		for (String s : list.keySet()) {
			if (!classesWithInterfaces.containsKey(s)) {
				classesWithInterfaces.put(s, list.get(s));
			}
		}
	}

	/**
	 * Ajoute les classes et de leurs supertype a l'attribut
	 * classesWithSuperTypes
	 * 
	 * @param list
	 */
	public void addClassesWithSuperTypes(HashMap<String, ArrayList<String>> list) {
		for (String s : list.keySet()) {
			if (!classesWithSuperTypes.containsKey(s)) {
				classesWithSuperTypes.put(s, list.get(s));
			}
		}
	}
	
	/**
	 * ajoute une interface en verifiant si elle n'a pas deja été ajoutée
	 */
	public void addInterface(String s) {
		if (!interfaces.contains(s)) {
			interfaces.add(s);
		}
	}

	/**
	 * Ajoute les interfaces et de leurs superinterfaces a l'attribut
	 * interfacesWithSuperInterFaces
	 * 
	 * @param list
	 */
	public void addInterfacesWithSuperInterFaces(
			HashMap<String, ArrayList<String>> list) {
		for (String s : list.keySet()) {
			if (!interfacesWithSuperInterFaces.containsKey(s)) {
				interfacesWithSuperInterFaces.put(s, list.get(s));
			}
		}
	}

	/**
	 * ajoute une primitive en verifiant si elle n'a pas deja été ajoutée
	 */
	public void addPrimitive(String s) {
		if (!primitives.contains(s)) {
			primitives.add(s);
		}
	}
	public ArrayList<String> getClasses() {
		return classes;
	}

	public HashMap<String, ArrayList<String>> getClassesWithInterfaces() {
		return classesWithInterfaces;
	}

	public HashMap<String, ArrayList<String>> getClassesWithSuperTypes() {
		return classesWithSuperTypes;
	}

	public ArrayList<String> getInterfaces() {
		return interfaces;
	}

	public HashMap<String, ArrayList<StringOperation>> getInterfacesWithOperations() {
		return interfacesWithOperations;
	}
	
	
	public HashMap<String, ArrayList<String>> getInterfacesWithSuperInterFaces() {
		return interfacesWithSuperInterFaces;
	}

	
	public ArrayList<String> getPrimitives() {
		return primitives;
	}
	/**
	 * Affiche les classes trouvées
	 */
	public void printClasses() {
		System.out
				.println("affichage des classes trouvées : " + classes.size());
		for (String s : classes) {
			System.out.println(s);
		}
	}
	/**
	 * Affichage des classes trouvées avec leurs supertypes
	 */
	public void printClassesWithSuperTypes() {
		for (String s : classesWithSuperTypes.keySet()) {
			System.out.println("class name : " + s);
			for (String st : classesWithSuperTypes.get(s)) {
				System.out.println(st);
			}
		}
	}
	/**
	 * Affichage des interfaces trouvées
	 */
	public void printInterfaces() {
		System.out.println("Affichage des interfaces");
		for (String s : interfaces) {
			System.out.println(s);
		}
	}
	/**
	 * Affichage des interfaces trouvées avec leurs operations
	 */
	public void printInterfacesWithOperation() {
		for (String s : interfacesWithOperations.keySet()) {
			System.out.println("interface name : " + s);
			for (StringOperation strop : interfacesWithOperations.get(s)) {
				strop.printOperation();
			}
		}
	}
	/**
	 * Affichage des primitives trouvées
	 */
	public void printPrimitives() {
		System.out.println("Primitives");
		for (String s : primitives) {
			System.out.println(s);
		}
	}
	/**
	 * Affichage d'un résumé des infos trouvées
	 */
	public void printSummary() {
		for (String s : classes) {
			System.out.println(s);
		}
		System.out.println("Nombre de classes trouvées : " + classes.size());

		System.out.println();
		System.out.println();

		for (String s : interfaces) {
			System.out.println(s);
		}
		System.out.println("Nombre d'interfaces trouvées : "
				+ interfaces.size());
		System.out.println();
		System.out.println();

		for (String s : primitives) {
			System.out.println(s);
		}
		System.out.println("Nombre de primitives trouvées : "
				+ primitives.size());
	}
	public void setClasses(ArrayList<String> classes) {
		this.classes = classes;
	}
	public void setClassesWithInterfaces(
			HashMap<String, ArrayList<String>> classesWithInterfaces) {
		this.classesWithInterfaces = classesWithInterfaces;
	}
	public void setClassesWithSuperTypes(
			HashMap<String, ArrayList<String>> classesWithSuperTypes) {
		this.classesWithSuperTypes = classesWithSuperTypes;
	}
	public void setInterfaces(ArrayList<String> interfaces) {
		this.interfaces = interfaces;
	}
	public void setInterfacesWithOperations(
			HashMap<String, ArrayList<StringOperation>> interfacesWithOperations) {
		this.interfacesWithOperations = interfacesWithOperations;
	}
	public void setInterfacesWithSuperInterFaces(
			HashMap<String, ArrayList<String>> interfacesWithSuperInterFaces) {
		this.interfacesWithSuperInterFaces = interfacesWithSuperInterFaces;
	}
	public void setPrimitives(ArrayList<String> primitives) {
		this.primitives = primitives;
	}
	
}
